#include <stdio.h>
#include <sys/types.h>
#include "V2xMessageEncode.h"
#include "V2xMessageDecode.h"

#define FILENAME    "asn1c_v2x_message"

#define FUNC_BEGIN  printf("[%s][%d] begin\n", __FUNCTION__, __LINE__)
#define FUNC_END    printf("[%s][%d] end\n", __FUNCTION__, __LINE__)

#define MAX_BUF_SIZE 256

#define IF_THEN_EXEC(condition, action) do {\
    if (condition) {                        \
        action;                             \
    }                                       \
} while(0)  

#define SAFE_FREE(x) do {\
    if (x) {             \
        free(x);         \
        x = NULL;        \
    }                    \
}while(0)    

/* Write the encoded output into some FILE stream. */
static int write_out(const void *buffer, size_t size, void *app_key) 
{
    FILE *out_fp = app_key;
    size_t wrote = fwrite(buffer, 1, size, out_fp);

    V2X_LOG_ERROR("write_out buffer:0x%x, size:%d\n", buffer, size);
    return (wrote == size) ? 0 : -1;
}

static uint8_t* RM_SDK_V2X_FillOctetString(OCTET_STRING_t* octetStr)
{
    const uint32_t size = 8;
    const uint8_t buf[8] = {0x10, 0x20, 0x30, };
    
    octetStr->buf = calloc(1, size);
    if (octetStr->buf == NULL)
    {
        return NULL;
    }

    memset(octetStr->buf, 0, size);
    memcpy(octetStr->buf, buf, size);
    octetStr->size = size;
    
    return octetStr->buf;
}

static int RM_SDK_V2X_MsgFrameEncodeTest()
{
    MessageFrame_t *msgFrame; /* Type to encode */
    BSM_t	       *bsm;
    uint8_t *octetStrBuf = NULL;
    asn_enc_rval_t ec; /* Encoder return value */
    
    /* Allocate the msgFrame_t */
    msgFrame = calloc(1, sizeof(MessageFrame_t)); /* not malloc! */
    if(!msgFrame) {
        perror("calloc() failed");
        exit(1);
    }
    
    /* Initialize the msgFrame members */
    msgFrame->present = MessageFrame_PR_bsmFrame;
    
    bsm = calloc(1, sizeof(BSM_t)); /* not malloc! */
    if(!bsm) {
        perror("calloc() failed");
        exit(1);
    }
    
    /* Initialize the msgFrame members */   
    bsm->msgCnt = 10; /* any random value */

    octetStrBuf = RM_SDK_V2X_FillOctetString(&bsm->id);
    bsm->plateNo = NULL;
    bsm->secMark = 1234;

    bsm->pos.lat = 12;
    bsm->pos.Long = 23;
    bsm->pos.elevation = NULL;

    bsm->accuracy.pos = 1;
    bsm->accuracy.elevation = NULL;
    
    bsm->transmission = 2;
    bsm->speed = 1234;
    bsm->heading = 456;

    bsm->accelSet.Long = 12;
    bsm->accelSet.lat = 34;
    bsm->accelSet.vert = 56;
    bsm->accelSet.yaw = 78;
    
    bsm->size.width = 90;
    bsm->size.vehicleLength = 100;
    
    bsm->vehicleClass.classification = 20;

    memcpy(&msgFrame->choice.bsmFrame, bsm, sizeof(BSM_t));
    
    FILE *fp = fopen(FILENAME, "wb"); /* for BER output */
    if(!fp) {
        perror(FILENAME);
        exit(1);
    }
    
    /* Encode the Rectangle type as PER (DER) */
    ec = uper_encode(&asn_DEF_MessageFrame, msgFrame, write_out, fp);
    fclose(fp);
    if(ec.encoded == -1) {
        fprintf(stderr, "Could not encode msgFrame (at %s)\n",
        ec.failed_type ? ec.failed_type->name : "unknown");
        exit(1);
    } else {
        fprintf(stderr, "Created %s with PER encoded msgFrame\n", FILENAME);
    }

    /* Also print the constructed msgFrame XER encoded (XML) */
    xer_fprint(stdout, &asn_DEF_MessageFrame, msgFrame);

    if (octetStrBuf)
    {
        free(octetStrBuf);
    }
     
    return 0;
}

static int RM_SDK_V2X_MsgFrameDecodeTest()
{
    char buf[1024]; /* Temporary buffer */
    asn_dec_rval_t rval; /* Decoder return value */
    MessageFrame_t *msgFrame = 0 ; /* Type to decode. Note this 01! */
    FILE *fp; /* Input file handler */
    size_t size; /* Number of bytes read */

    /* Open input file as read-only binary */
    fp = fopen(FILENAME, "rb");
    if(!fp) {
        perror(FILENAME);
        exit(1);
    }
    /* Read up to the buffer size */
    size = fread(buf, 1, sizeof(buf), fp);
    fclose(fp);
    
    if(!size) {
        fprintf(stderr, "%s: Empty or broken\n", FILENAME);
        exit(1);
    }

    /* Decode the input buffer as Rectangle type */
    rval = uper_decode(0, &asn_DEF_MessageFrame, (void **)&msgFrame, buf, size, 0, 0);
    if(rval.code != RC_OK) {
        fprintf(stderr, "%s: Broken Rectangle encoding at byte %ld\n", FILENAME,
        (long)rval.consumed);
        exit(1);
    }
    /* Print the decoded Rectangle type as XML */
    xer_fprint(stdout, &asn_DEF_MessageFrame, msgFrame);
    
    return 0; /* Decoding finished successfully */
}

static int RM_SDK_V2X_BSMEncode()
{
    BSM_t *bsm;
    uint8_t *octetStrBuf = NULL;
    asn_enc_rval_t ec; /* Encoder return value */
    
    /* Allocate the msgFrame_t */
    bsm = calloc(1, sizeof(BSM_t)); /* not malloc! */
    if(!bsm) {
        perror("calloc() failed");
        exit(1);
    }
    
    /* Initialize the msgFrame members */ 
    bsm->msgCnt = 10; /* any random value */

    octetStrBuf = RM_SDK_V2X_FillOctetString(&bsm->id);
    bsm->plateNo = NULL;
    bsm->secMark = 1234;

    bsm->pos.lat = 12;
    bsm->pos.Long = 23;
    bsm->pos.elevation = NULL;

    bsm->accuracy.pos = 1;
    bsm->accuracy.elevation = NULL;
    
    bsm->transmission = 2;
    bsm->speed = 1234;
    bsm->heading = 456;

    bsm->accelSet.Long = 12;
    bsm->accelSet.lat = 34;
    bsm->accelSet.vert = 56;
    bsm->accelSet.yaw = 78;
    
    bsm->size.width = 90;
    bsm->size.vehicleLength = 100;
    
    bsm->vehicleClass.classification = 20;

    FILE *fp = fopen(FILENAME, "wb"); /* for BER output */
    if(!fp) {
        perror(FILENAME);
        exit(1);
    }
    
    /* Encode the BSM type as XPER (DER) */
    ec = uper_encode(&asn_DEF_BSM, bsm, write_out, fp);
    fclose(fp);
    if(ec.encoded == -1) {
        fprintf(stderr, "Could not encode bsm (at %s)\n",
        ec.failed_type ? ec.failed_type->name : "unknown");
        exit(1);
    } else {
        fprintf(stderr, "Created %s with uper encoded bsm\n", FILENAME);
    }

    /* Also print the constructed msgFrame XER encoded (XML) */
    xer_fprint(stdout, &asn_DEF_BSM, bsm);

    if (octetStrBuf)
    {
        free(octetStrBuf);
    }
    return 0; /* Encoding finished successfully */
}

static int RM_SDK_V2X_BSMDecode()
{
    char buf[1024]; /* Temporary buffer */
    asn_dec_rval_t rval; /* Decoder return value */
    BSM_t *bsm = 0 ; /* Type to decode. Note this 01! */
    FILE *fp; /* Input file handler */
    size_t size; /* Number of bytes read */

    /* Open input file as read-only binary */
    fp = fopen(FILENAME, "rb");
    if(!fp) {
        perror(FILENAME);
        exit(1);
    }
    /* Read up to the buffer size */
    size = fread(buf, 1, sizeof(buf), fp);
    fclose(fp);
    
    if(!size) {
        fprintf(stderr, "%s: Empty or broken\n", FILENAME);
        exit(1);
    }

    /* Decode the input buffer as Rectangle type */
    rval = uper_decode(0, &asn_DEF_BSM, (void **)&bsm, buf, size, 0, 0);
    if(rval.code != RC_OK) {
        fprintf(stderr, "%s: Broken bsm encoding at byte %ld\n", FILENAME,
        (long)rval.consumed);
        exit(1);
    }
    /* Print the decoded Rectangle type as XML */
    xer_fprint(stdout, &asn_DEF_BSM, bsm);
    
    return 0; /* Decoding finished successfully */
}

void message_frame_test()
{
    FUNC_BEGIN;
    RM_SDK_V2X_MsgFrameEncodeTest();
    RM_SDK_V2X_MsgFrameDecodeTest();
    FUNC_END;
}

void bsm_msg_test1()
{
    FUNC_BEGIN;
    RM_SDK_V2X_BSMEncode();
    RM_SDK_V2X_BSMDecode();
    FUNC_END;
}

void writeEncodeData2File(char* fileName, uint8_t* buffer, uint32_t size)
{
    FILE *fp = fopen(fileName, "wb"); /* for BER output */
    if(!fp) {
        perror(fileName);
        exit(1);
    }

    fwrite(buffer, 1, size, fp);
    fclose(fp);
    V2X_LOG_ERROR("write2file size:%d\n", size);
}

void bsm_msg_fill(MessageFrame_t *msgFrame)
{
    BSM_t *bsm;    
    
    msgFrame->present = MessageFrame_PR_bsmFrame;
    bsm = &msgFrame->choice.bsmFrame;

    bsm->msgCnt = 10; /* any random value */

    RM_SDK_V2X_FillOctetString(&bsm->id);
    bsm->plateNo = NULL;
    bsm->secMark = 1234;

    bsm->pos.lat = 12;
    bsm->pos.Long = 23;
    bsm->pos.elevation = NULL;

    bsm->accuracy.pos = 1;
    bsm->accuracy.elevation = NULL;
    
    bsm->transmission = 2;
    bsm->speed = 1234;
    bsm->heading = 456;

    bsm->accelSet.Long = 12;
    bsm->accelSet.lat = 34;
    bsm->accelSet.vert = 56;
    bsm->accelSet.yaw = 78;
    
    bsm->size.width = 90;
    bsm->size.vehicleLength = 100;
    
    bsm->vehicleClass.classification = 20;
    
    V2X_LOG_ERROR("fill bsm end\n");
}

void map_msg_fill(MessageFrame_t *msgFrame)
{
    MAP_t *map;

    Node_t *mapNode = calloc(1, sizeof(Node_t));

    mapNode->name = NULL;
    mapNode->id.region = NULL;
    mapNode->id.id = 1;
    mapNode->refPos.lat = 10;
    mapNode->refPos.Long = 20;
    mapNode->refPos.elevation = NULL;
    mapNode->inLinks = NULL;
    
    msgFrame->present = MessageFrame_PR_mapFrame;
    map = &msgFrame->choice.mapFrame;

    map->msgCnt = 20;
    map->timeStamp = calloc(1, sizeof(MinuteOfTheYear_t));
    *map->timeStamp = 30;

    map->nodes.list.array = calloc(1, sizeof(Node_t));
    map->nodes.list.array[0] = mapNode;
    map->nodes.list.count = 1;
    map->nodes.list.size = 1;
    map->nodes.list.free = NULL;
}

void map_msg_free(MAP_t *map)
{
    SAFE_FREE(map->timeStamp); 
    SAFE_FREE(map->nodes.list.array[0]);
    SAFE_FREE(map->nodes.list.array);
}

void rsm_msg_fill(MessageFrame_t *msgFrame)
{
    RSM_t *rsm;
    ParticipantData_t *partiData = calloc(1, sizeof(ParticipantData_t));
    
    msgFrame->present = MessageFrame_PR_rsmFrame;
    rsm = &msgFrame->choice.rsmFrame;

    rsm->msgCnt = 20;
    RM_SDK_V2X_FillOctetString(&rsm->id);

    rsm->refPos.lat = 30;
    rsm->refPos.Long = 40;
    rsm->refPos.elevation = NULL;

    partiData->ptcType = 1;
    partiData->ptcId = 20;
    partiData->source = 3;
    partiData->id = NULL;
    partiData->plateNo = NULL;
    partiData->secMark = 40;
    partiData->pos.offsetLL.present = PositionOffsetLL_PR_position_LL1;
    partiData->pos.offsetLL.choice.position_LL1.lon = 50;
    partiData->pos.offsetLL.choice.position_LL1.lat = 60;
    partiData->pos.offsetV = NULL;
    partiData->accuracy.pos = 2;
    partiData->accuracy.elevation = NULL;
    partiData->transmission = NULL;
    partiData->speed = 80;
    partiData->heading = 90;
    partiData->angle = NULL;
    partiData->motionCfd = NULL;
    partiData->accelSet = NULL;
    partiData->size.width = 100;
    partiData->size.vehicleLength = 110;
    partiData->size.vehicleHeight = NULL;
    partiData->vehicleClass = NULL;
    
    rsm->participants.list.array = calloc(1, sizeof(ParticipantData_t));
    rsm->participants.list.array[0] = partiData;
    rsm->participants.list.count = 1;
    rsm->participants.list.size = 1;
    rsm->participants.list.free = NULL;
}

void rsm_msg_free(RSM_t *rsm)
{
    SAFE_FREE(rsm->id.buf); 
    SAFE_FREE(rsm->participants.list.array[0]);
    SAFE_FREE(rsm->participants.list.array);
}

void rsi_msg_fill(MessageFrame_t *msgFrame)
{
    RSI_t *rsi;
    PositionOffsetLLV_t *posllv = calloc(2, sizeof(PositionOffsetLLV_t));
    PositionOffsetLLV_t *first = posllv;
    
    msgFrame->present = MessageFrame_PR_rsiFrame;
    rsi = &msgFrame->choice.rsiFrame;

    rsi->msgCnt = 20;
    rsi->timeStamp = NULL;
    RM_SDK_V2X_FillOctetString(&rsi->id);

    rsi->rsiId = 22;

    rsi->alertType = 1;
    rsi->description = NULL;
    rsi->priority = NULL;
    
    rsi->refPos.lat = 30;
    rsi->refPos.Long = 40;
    rsi->refPos.elevation = NULL;

    posllv->offsetLL.present = PositionOffsetLL_PR_position_LL1;
    posllv->offsetLL.choice.position_LL1.lon = 1;
    posllv->offsetLL.choice.position_LL1.lat = 10;
    posllv->offsetV = NULL;

    posllv += 1;
    posllv->offsetLL.present = PositionOffsetLL_PR_position_LL1;
    posllv->offsetLL.choice.position_LL1.lon = 2;
    posllv->offsetLL.choice.position_LL1.lat = 20;
    posllv->offsetV = NULL;
    
    rsi->alertPath.list.array = calloc(2, sizeof(PositionOffsetLLV_t));
    rsi->alertPath.list.array[0] = first;
    rsi->alertPath.list.array[1] = posllv;
    rsi->alertPath.list.count = 2;
    rsi->alertPath.list.size = 2;
    rsi->alertPath.list.free = NULL;

    rsi->alertRadius = 100;
}

void rsi_msg_free(RSI_t *rsi)
{
    SAFE_FREE(rsi->id.buf); 
    SAFE_FREE(rsi->alertPath.list.array[0]);
    SAFE_FREE(rsi->alertPath.list.array);
}

void spat_msg_fill(MessageFrame_t *msgFrame)
{
    SPAT_t *spat;
    IntersectionState_t *interSecState = calloc(1, sizeof(IntersectionState_t));
    
    msgFrame->present = MessageFrame_PR_spatFrame;
    spat = &msgFrame->choice.spatFrame;

    spat->msgCnt = 10;
    spat->timeStamp = calloc(1, sizeof(MinuteOfTheYear_t));
    *spat->timeStamp = 20;
    spat->name = NULL;

    PhaseState_t* phaseState = calloc(1, sizeof(PhaseState_t));
    phaseState->light = 2;
    phaseState->timing = NULL;
    
    Phase_t *phase = calloc(1, sizeof(Phase_t));

    phase->id = 30;
    phase->phaseStates.list.array = calloc(1, sizeof(PhaseState_t));
    phase->phaseStates.list.array[0] = phaseState;
    phase->phaseStates.list.count = 1;
    phase->phaseStates.list.size = 1;
    phase->phaseStates.list.free = NULL;
    
    memset(interSecState, 0, sizeof(IntersectionState_t));
    interSecState->intersectionId.region = NULL;
    interSecState->intersectionId.id = 30;
    interSecState->status.buf = calloc(1, 2);
    interSecState->status.buf[0] = 0x10;
    interSecState->status.buf[1] = 0x20;
    interSecState->status.size = 2;
    interSecState->status.bits_unused = 0;
    interSecState->moy = NULL;
    interSecState->timeStamp = NULL;

    interSecState->phases.list.array = calloc(1, sizeof(Phase_t));
    interSecState->phases.list.array[0] = phase;
    interSecState->phases.list.count = 1;
    interSecState->phases.list.size = 1;
    interSecState->phases.list.free = NULL;    
    
    spat->intersections.list.array = calloc(1, sizeof(IntersectionState_t));
    spat->intersections.list.array[0] = interSecState;
    spat->intersections.list.count = 1;
    spat->intersections.list.size = 1;
    spat->intersections.list.free = NULL;
}

void spat_msg_free(SPAT_t *spat)
{
    IntersectionState_t *interSecState = spat->intersections.list.array[0];
    Phase_t *phase = interSecState->phases.list.array[0];
    PhaseState_t* phaseState = phase->phaseStates.list.array[0];
    
    SAFE_FREE(phaseState);
    SAFE_FREE(phase->phaseStates.list.array);
    
    SAFE_FREE(phase); 
    SAFE_FREE(interSecState->phases.list.array); 
    SAFE_FREE(interSecState->status.buf);
    
    SAFE_FREE(interSecState);
    SAFE_FREE(spat->timeStamp); 
    SAFE_FREE(spat->intersections.list.array);
}

void bsm_msg_test()
{
    FUNC_BEGIN;
    MessageFrame_t msgFrame;
    MessageFrame_t *msgFrameOut;
    uint32_t size;
    V2xMsgEncodeBuf_t msgBuf;

    memset(&msgFrame, 0, sizeof(MessageFrame_t));
    
    bsm_msg_fill(&msgFrame);
    
    msgBuf.buffer = calloc(1, MAX_BUF_SIZE);
    msgBuf.maxSize = MAX_BUF_SIZE;
    msgBuf.realSize = 0;

    V2X_LOG_ERROR("----------bsm encode---------\n");
    RM_SDK_V2X_MsgFrameEncode(&msgFrame, &msgBuf);

    V2X_LOG_ERROR("----------bsm decode---------\n");
    msgFrameOut = RM_SDK_V2X_MsgFrameDecode(msgBuf.buffer, msgBuf.realSize);
    RM_SDK_V2X_DecodeBufFree(MessageFrame_PR_NOTHING, msgFrameOut);
#if 0    
    if (msgFrameOut)
    {
        printf("[%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d]\n", 
            msgFrameOut->present, msgFrameOut->choice.bsmFrame.msgCnt,
            msgFrameOut->choice.bsmFrame.id.buf[0],msgFrameOut->choice.bsmFrame.id.size,
            msgFrameOut->choice.bsmFrame.secMark,msgFrameOut->choice.bsmFrame.pos.lat,
            msgFrameOut->choice.bsmFrame.pos.Long,msgFrameOut->choice.bsmFrame.accuracy.pos,
            msgFrameOut->choice.bsmFrame.accuracy.elevation,msgFrameOut->choice.bsmFrame.transmission,
            msgFrameOut->choice.bsmFrame.speed,msgFrameOut->choice.bsmFrame.heading,
            msgFrameOut->choice.bsmFrame.accelSet.Long,msgFrameOut->choice.bsmFrame.accelSet.lat,
            msgFrameOut->choice.bsmFrame.accelSet.vert,msgFrameOut->choice.bsmFrame.accelSet.yaw,
            msgFrameOut->choice.bsmFrame.size.width,msgFrameOut->choice.bsmFrame.size.vehicleLength,
            msgFrameOut->choice.bsmFrame.vehicleClass.classification);
    }
#endif
    writeEncodeData2File("asn1c_bsm", msgBuf.buffer, msgBuf.realSize);

    SAFE_FREE(msgBuf.buffer);
    SAFE_FREE(msgFrame.choice.bsmFrame.id.buf);
    FUNC_END;
}

void map_msg_test()
{
    FUNC_BEGIN;
    MessageFrame_t msgFrame;
    MessageFrame_t *msgFrameOut;
    uint32_t size;
    V2xMsgEncodeBuf_t msgBuf;

    memset(&msgFrame, 0, sizeof(MessageFrame_t));
    
    map_msg_fill(&msgFrame);
    
    msgBuf.buffer = calloc(1, MAX_BUF_SIZE);
    msgBuf.maxSize = MAX_BUF_SIZE;
    msgBuf.realSize = 0;

    V2X_LOG_ERROR("----------map encode---------\n");
    RM_SDK_V2X_MsgFrameEncode(&msgFrame, &msgBuf);

    V2X_LOG_ERROR("----------map decode---------\n");
    msgFrameOut = RM_SDK_V2X_MsgFrameDecode(msgBuf.buffer, msgBuf.realSize);
    RM_SDK_V2X_DecodeBufFree(MessageFrame_PR_NOTHING, msgFrameOut);
    
    writeEncodeData2File("asn1c_map", msgBuf.buffer, msgBuf.realSize);

    map_msg_free(&msgFrame.choice.mapFrame); 
    SAFE_FREE(msgBuf.buffer);
    FUNC_END;
}

void rsm_msg_test()
{
    FUNC_BEGIN;
    MessageFrame_t msgFrame;
    MessageFrame_t *msgFrameOut;
    uint32_t size;
    V2xMsgEncodeBuf_t msgBuf;

    memset(&msgFrame, 0, sizeof(MessageFrame_t));
    
    rsm_msg_fill(&msgFrame);
    
    msgBuf.buffer = calloc(1, MAX_BUF_SIZE);
    msgBuf.maxSize = MAX_BUF_SIZE;
    msgBuf.realSize = 0;

    V2X_LOG_ERROR("----------rsm encode---------\n");
    RM_SDK_V2X_MsgFrameEncode(&msgFrame, &msgBuf);

    V2X_LOG_ERROR("----------rsm decode---------\n");
    msgFrameOut = RM_SDK_V2X_MsgFrameDecode(msgBuf.buffer, msgBuf.realSize);
    RM_SDK_V2X_DecodeBufFree(MessageFrame_PR_NOTHING, msgFrameOut);
    
    writeEncodeData2File("asn1c_rsm", msgBuf.buffer, msgBuf.realSize);
    
    rsm_msg_free(&msgFrame.choice.rsmFrame);
    SAFE_FREE(msgBuf.buffer);
    FUNC_END;
}

void rsi_msg_test()
{
    FUNC_BEGIN;
    MessageFrame_t msgFrame;
    MessageFrame_t *msgFrameOut;
    uint32_t size;
    V2xMsgEncodeBuf_t msgBuf;

    memset(&msgFrame, 0, sizeof(MessageFrame_t));
    
    rsi_msg_fill(&msgFrame);
    
    msgBuf.buffer = calloc(1, MAX_BUF_SIZE);
    msgBuf.maxSize = MAX_BUF_SIZE;
    msgBuf.realSize = 0;

    V2X_LOG_ERROR(("----------rsi encode---------\n"));
    RM_SDK_V2X_MsgFrameEncode(&msgFrame, &msgBuf);

    V2X_LOG_ERROR(("----------rsi decode---------\n"));
    msgFrameOut = RM_SDK_V2X_MsgFrameDecode(msgBuf.buffer, msgBuf.realSize);
    RM_SDK_V2X_DecodeBufFree(MessageFrame_PR_NOTHING, msgFrameOut);
    
    writeEncodeData2File("asn1c_rsi", msgBuf.buffer, msgBuf.realSize);
    
    rsi_msg_free(&msgFrame.choice.rsiFrame);
    SAFE_FREE(msgBuf.buffer);
    FUNC_END;
}

void spat_msg_test()
{
    FUNC_BEGIN;
    MessageFrame_t msgFrame;
    MessageFrame_t *msgFrameOut;
    uint32_t size;
    V2xMsgEncodeBuf_t msgBuf;

    memset(&msgFrame, 0, sizeof(MessageFrame_t));
    
    spat_msg_fill(&msgFrame);
    
    msgBuf.buffer = calloc(1, MAX_BUF_SIZE);
    msgBuf.maxSize = MAX_BUF_SIZE;
    msgBuf.realSize = 0;

    V2X_LOG_ERROR(("----------spat encode---------\n"));
    RM_SDK_V2X_MsgFrameEncode(&msgFrame, &msgBuf);

    V2X_LOG_ERROR(("----------spat decode---------\n"));
    msgFrameOut = RM_SDK_V2X_MsgFrameDecode(msgBuf.buffer, msgBuf.realSize);
    RM_SDK_V2X_DecodeBufFree(MessageFrame_PR_NOTHING, msgFrameOut);
    
    writeEncodeData2File("asn1c_spat", msgBuf.buffer, msgBuf.realSize);
    
    spat_msg_free(&msgFrame.choice.spatFrame);
    SAFE_FREE(msgBuf.buffer);
    FUNC_END;
}

int main() 
{
    bsm_msg_test();
    map_msg_test();
    rsm_msg_test();
    rsi_msg_test();
    spat_msg_test();
    return 0;
}

